#ifndef GAMEOBJECT_H_INCLUDED
#define GAMEOBJECT_H_INCLUDED
#include <map>
#include "File.h"
#include "Singleton.h"
#include "Vec3.h"
#include "Matrix.h"
#include "MeshManager.h"
#include "btBulletDynamicsCommon.h"

#define BIT(x) (1<<(x))
class ObjMesh;


class GameObject //: public RefCounted
{
public:

	//Bullet collision flags
	enum collisiontypes 
	{
		COL_NOTHING = 0, //<Collide with nothing
		COL_BALL = BIT(0), //<Collide with ships
		COL_TERRAIN = BIT(1), //<Collide with walls
		COL_CATAPULT = BIT(2), //<Collide with powerups
		COL_TARGET = BIT(3)
	};

	int ballCollidesWith;
	int terrainCollidesWith;
	int catapultCollidesWith;
	int targetCollidesWith;

	GameObject();
	virtual ~GameObject() {}
	virtual void Draw() {}
	virtual void Update() = 0;
	
	virtual const char* GetTypeName() = 0;
	virtual bool Load(File* const f);
	void SetId(int newId);
	
	inline Vec3f GetPos() { return m_pos; }
	inline void SetPos(const Vec3f pos) { m_pos = pos; }
	inline Vec3f GetVel() { return m_vel; }
	inline void SetVel(const Vec3f vel) { m_vel = vel; }
	inline Vec3f GetAcc() { return m_acc; }
	inline void SetAcc(const Vec3f acc) { m_acc = acc; }

	//Bullet Functions
	void MakeStaticCollisionShapeFromMesh(ObjMesh* mesh, float mass);
	void MakeStaticCollisionShapeFromMesh(ObjMesh* mesh, float mass, int collGroup, int collisionMask);
	void MakeDynamicCollisionShapeFromMesh(ObjMesh* mesh, float mass);
	void CreateCollisionShape(btCollisionShape* shape, float mass);
	void CreateCollisionShape(btCollisionShape* shape, float mass, int collGroup, int collisionMask);
	btDefaultMotionState* GetMotionState();
	btRigidBody* GetRigidBody();
	virtual void BTCollided(GameObject* go, const btVector3& aAng, const btVector3& aLin) { };

protected:
	int m_id;
	std::string m_texPath;
	std::string m_meshPath;
	Vec3f m_pos;
	Vec3f m_vel;
	Vec3f m_acc;
	Vec3f m_rotation;


	Matrix m_mat;

	//Bullet collision variables
	float m_angularDamping;
	float m_linearDamping;
	

	btCollisionShape* mp_collShape;
	btScalar m_mass;
	bool m_isDynamic;
	btVector3 m_localInertia;
	btRigidBody* mp_rigidBody;
	btDefaultMotionState* mp_motionState;
	
};
//typedef SmartPtr<GameObject> spGameObject*;
typedef std::map<unsigned int, GameObject*> GameObjectsMap;



#endif

